﻿using AForge.Video;
using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DAL;
using OOAD_PROJEKAT;

namespace kamera
{
    public partial class MainWindow : Window
    {
        VideoCaptureDevice LocalWebCam;
        public FilterInfoCollection LoaclWebCamsCollection;

        BitmapImage bi = null;

        void Cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            try
            {
                System.Drawing.Image img = (Bitmap)eventArgs.Frame.Clone();

                MemoryStream ms = new MemoryStream();
                img.Save(ms, ImageFormat.Bmp);
                ms.Seek(0, SeekOrigin.Begin);
                bi = new BitmapImage();
                bi.BeginInit();
                bi.StreamSource = ms;
                bi.EndInit();

                bi.Freeze();


                postaviVideo(bi);

                /*
                Dispatcher.BeginInvoke(new ThreadStart(delegate
                {
                    frameHolder.Source = bi;
                }));
          */

            }
            catch (Exception ex)
            {
            }
        }

        public List<byte> pattern = new List<byte>();

        public MainWindow()
        {
            InitializeComponent();
            LoaclWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            izbor.SelectedIndex = -1;

            foreach (FilterInfo f in LoaclWebCamsCollection)
            {
                izbor.Items.Add(f.Name);
            }
            for (int i = 0; i < 200; i++)
            {
                pattern.Add((byte)i);
            }

            popuniListu();





        }

        System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();

        bool snimaSe = false;

        private void Button_Click(object sender, RoutedEventArgs e)
        {

            if (izbor.SelectedIndex == -1)
                global::System.Windows.MessageBox.Show("Nije odabrana nijedna kamera");
            else
            {
                try
                {
                    dispatcherTimer.Tick += new EventHandler(pocniSnimanje);
                    dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);





                    LocalWebCam = new VideoCaptureDevice(LoaclWebCamsCollection[izbor.SelectedIndex].MonikerString);
                    LocalWebCam.NewFrame += new NewFrameEventHandler(Cam_NewFrame);
                    LocalWebCam.Start();
                    dispatcherTimer.Start();

                }
                catch (Exception ex)
                { }
            }
        }

        private void pocniSnimanje(object sender, EventArgs e)
        {
            try
            {
                byte[] data;
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();

                encoder.Frames.Add(BitmapFrame.Create(bi));

                using (MemoryStream ms = new MemoryStream())
                {
                    encoder.Save(ms);
                    data = ms.ToArray();
                }


                if (snimka == null)
                    snimka = data.ToList<byte>();
                else
                {
                    snimka.AddRange(data.ToList<byte>());
                    snimka.AddRange(pattern);
                }

            }
            catch (Exception ex)
            {

            }
        }

        public string ImageToBase64(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat format)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, format);
                byte[] imageBytes = ms.ToArray();

                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }

        public System.Drawing.Image Base64ToImage(string base64String)
        {
            // Convert Base64 String to byte[]
            byte[] imageBytes = Convert.FromBase64String(base64String);
            MemoryStream ms = new MemoryStream(imageBytes, 0,
              imageBytes.Length);

            // Convert byte[] to Image
            ms.Write(imageBytes, 0, imageBytes.Length);
            System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
            return image;
        }

        public void popuniListu()
        {
            try
            {
                DAL.DAL d = DAL.DAL.Instanca;
                d.kreirajKonekciju("localhost", "osiguranje", "root", "");
                DAL.DAL.videoDAO sd = d.getDAO.getVideoDAO();
                List<video> vid = sd.getAll();

                listaSnimaka.Items.Clear();
                foreach (video v in vid)
                {
                    listaSnimaka.Items.Add(v);
                }


            }
            catch (Exception exx)
            {

            }

        }



        List<byte> snimka = new List<byte>();

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {

                byte[] data;
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bi));
                using (MemoryStream ms = new MemoryStream())
                {
                    encoder.Save(ms);
                    data = ms.ToArray();
                }


                if (snimka == null)
                    snimka = data.ToList<byte>();
                else
                {
                    snimka.AddRange(data.ToList<byte>());
                    snimka.AddRange(pattern);
                }

            }
            catch (Exception ex)
            {

            }
        }

        /*
        public BitmapImage ToImage(byte[] array)
        {
            using (var stream = new MemoryStream(array))
            {
                var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                BitmapImage pom = new BitmapImage();
               
                return decoder.Frames[0];
            }
        }*/

        public BitmapImage ToImage(byte[] byteVal)
        {
            if (byteVal == null) return null;


            try
            {
                MemoryStream strmImg = new MemoryStream(byteVal);
                BitmapImage myBitmapImage = new BitmapImage();
                myBitmapImage.BeginInit();
                myBitmapImage.StreamSource = strmImg;
                myBitmapImage.DecodePixelWidth = 200;
                myBitmapImage.EndInit();

                return myBitmapImage;
            }
            catch (Exception ex)
            {

                return null;
            }


        }


        List<byte> biti = new List<byte>();
        List<byte> praviBiti = new List<byte>();

        int pom = 0;
        int procitano = 0;

        bool pustenVideo = false;

        bool otvaranVideo = false;



        private void Button_Click_2(object sender, RoutedEventArgs e) //PLAY
        {

            if (listaSnimaka.SelectedIndex == -1)
            {
                global::System.Windows.MessageBox.Show("Odaberite snimak");
                return;
            }
            pustenVideo = true;
            try
            {
                string citanje = null;

                DAL.DAL d = DAL.DAL.Instanca;
                d.kreirajKonekciju("localhost", "osiguranje", "root", "");
                DAL.DAL.videoDAO sd = d.getDAO.getVideoDAO();
                video v = new video(new List<byte>());
                v = sd.read(new video((listaSnimaka.SelectedItem as video).id, DateTime.Now, new List<byte>()));


                ///////////String.Join("",snimka.ToArray())


                biti.AddRange(v.snimak);
                System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
                dispatcherTimer.Tick += new EventHandler(prikazVidea);
                dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);

                if (!otvaranVideo)
                {
                    dispatcherTimer.Start();
                    otvaranVideo = true;
                }

            }
            catch (Exception x)
            {

            }
        }

        public void postaviVideo(BitmapImage b)
        {
            this.Dispatcher.Invoke(new Action(() => frameHolder.Source = bi));

        }

        public void postaviNesta(bool vrijednost)
        {
            this.Dispatcher.Invoke(new Action(() => pustenVideo = false));

        }

        public void prikazVidea(object sender, EventArgs e)
        {
            if (!pustenVideo) return;
            for (int i = procitano; i < biti.Count; i++)
            {
                byte bp = biti[i];

                if (bp == pattern[pom])
                {
                    pom++;
                }

                praviBiti.Add(bp);

                if (pom == pattern.Count && praviBiti.Count > 10000)
                {

                    for (int j = 0; j < pattern.Count; j++)
                        praviBiti.RemoveAt(praviBiti.Count - 1);

                    pom = 0;

                    BitmapImage b = ToImage(praviBiti.ToArray());
                    ImageSource si = b;
                    slika.Source = si;
                    praviBiti.Clear();
                    procitano = i + 1;
                    return;

                }
                else if (pom == pattern.Count)
                {
                    pom = 0;
                    praviBiti.Clear();
                }
            }

        }

        private void Button_Click_3(object sender, RoutedEventArgs e) // STOP
        {
            dispatcherTimer.Stop();


            try
            {
                DAL.DAL d = DAL.DAL.Instanca;
                d.kreirajKonekciju("localhost", "osiguranje", "root", "");
                DAL.DAL.videoDAO sd = d.getDAO.getVideoDAO();
                video v = new video(snimka);
                sd.create(v);
                popuniListu();
                biti = new List<byte>();
                snimka = new List<byte>();

            }
            catch (Exception exx)
            {

            }

        }

        private void Button_Click_4(object sender, RoutedEventArgs e) // stop snimke
        {
            pustenVideo = false;
        }

    }





}
